﻿using Logger.Service.Interface;
using System.Net.WebSockets;
using System.Text;
using WebSocketApi.SocketHandler;

namespace WebSocketApi.Middleware
{
    public class MySocketMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ISocketServiceHandler _handler;
        private readonly ILoggerContext _logger;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="next"></param>
        /// <param name="handler"></param>
        /// <param name="logger"></param>
        public MySocketMiddleware(RequestDelegate next, ISocketServiceHandler handler, ILoggerContext logger)
        {
            _next = next;
            _handler = handler;
            _logger = logger;
        }

        /// <summary>
        /// 根据状态处理
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext context)
        {
            if (context.WebSockets.IsWebSocketRequest)
            {
                var socket = await context.WebSockets.AcceptWebSocketAsync();
                //保存socket对象
                await _handler.OnConnectedAsync(socket);
                //客户端请求头
                //VerifyRequestParam(context); 
                try
                {
                    //消息缓冲区10M
                    var buffer = new byte[1024 * 1024 * 10];
                    while (socket.State == WebSocketState.Open)
                    {
                        var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

                        switch (result.MessageType)
                        {
                            case WebSocketMessageType.Text:
                                var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                                _ = _handler.ReceiveTextAsync(socket, message);
                                break;
                            case WebSocketMessageType.Binary:
                                _ = _handler.ReceiveFileAsync(socket, result, buffer);
                                break;
                            case WebSocketMessageType.Close:
                                _ = _handler.OnDisconnectedAsync(socket);
                                break;
                            default:
                                throw new ArgumentOutOfRangeException();
                        }
                    }
                }
                catch (Exception e)
                {
                    _ = _handler.OnDisconnectedAsync(socket);
                    _logger.Error($"处理Socket状态发生异常,Exception:{e}");
                    Console.WriteLine(e);
                }
            }
            else
            {
                await _next(context);
            }
        }

        /// <summary>
        /// 获取WebSocket请求附加的参数
        /// </summary>
        /// <param name="context"></param>
        private void VerifyRequestParam(HttpContext context)
        {
            if (context?.Request.Headers != null)
            {
                Console.WriteLine("客户端请求参数...");
                foreach (var (key, value) in context.Request.Headers)
                {
                    Console.WriteLine("Request:" + key + ":" + value);
                }
            }
        }

    }
}
